#!/usr/bin/env python3
# -*- coding=utf-8 -*-
# 本脚由亁颐堂现任明教教主编写，用于乾颐盾Python课程！
# 教主QQ:605658506
# 亁颐堂官网www.qytang.com
# 教主技术进化论拓展你的技术新边疆
# https://ke.qq.com/course/271956?tuin=24199d8a

from django.shortcuts import render
from devnet.models import Department, Navbar, SNMPtype, DeviceSNMP, Devicetype, Devicedb, MonitorInterval
from devnet.forms import AddDeviceType, EditDeviceType
from devnet.forms import AddDevice, EditDevice
from django.db.models import Max
from datetime import datetime, timedelta
from django.contrib.auth.decorators import permission_required

try:
    cpu_max_interval = MonitorInterval.objects.get(name='cpu_max_interval').interval
except MonitorInterval.DoesNotExist:
    c = MonitorInterval(name='cpu_max_interval',
                        interval=1)
    c.save()
    cpu_max_interval = MonitorInterval.objects.get(name='cpu_max_interval').interval


try:
    mem_max_interval = MonitorInterval.objects.get(name='mem_max_interval').interval
except MonitorInterval.DoesNotExist:
    m = MonitorInterval(name='mem_max_interval',
                        interval=1)
    m.save()
    mem_max_interval = MonitorInterval.objects.get(name='mem_max_interval').interval


@permission_required(['devnet.add_devicetype', 'devnet.add_devicesnmp'])
def add_device_type(request):
    html_title = Department.objects.get(name='admin').departtitle.title
    navbar_list = []
    for navbar in Navbar.objects.all().order_by('id'):
        navbar_list.append([navbar.name, navbar.url])
    active_navbar = '设备管理'
    sidebar_list = []
    for sidebar in Navbar.objects.get(name='设备管理').Sidebar.all().order_by('id'):
        sidebar_list.append([sidebar.name, sidebar.url])
    active_sidebar = '添加设备类型'
    if request.method == 'POST':
        form = AddDeviceType(request.POST)
        if form.is_valid():
            device_type_name = request.POST.get('device_type_name')
            oid_list = []
            cpu_usage = request.POST.get('cpu_usage')
            oid_list.append(['cpu_usage', cpu_usage])
            mem_usage = request.POST.get('mem_usage')
            oid_list.append(['mem_usage', mem_usage])
            mem_free = request.POST.get('mem_free')
            oid_list.append(['mem_free', mem_free])
            if_name = request.POST.get('if_name')
            oid_list.append(['if_name', if_name])
            if_speed = request.POST.get('if_speed')
            oid_list.append(['if_speed', if_speed])
            if_state = request.POST.get('if_state')
            oid_list.append(['if_state', if_state])
            if_in_bytes = request.POST.get('if_in_bytes')
            oid_list.append(['if_in_bytes', if_in_bytes])
            if_out_bytes = request.POST.get('if_out_bytes')
            oid_list.append(['if_out_bytes', if_out_bytes])

            d = Devicetype(type_name=device_type_name)
            d.save()
            for x in oid_list:
                ds = DeviceSNMP(device_type=d,
                                snmp_type=SNMPtype.objects.get(snmp_type=x[0]),
                                oid=x[1])
                ds.save()
            successmessage = '设备类型添加成功!'
            return render(request, 'devnet_add_device_type.html', locals())
        else:
            return render(request, 'devnet_add_device_type.html', locals())
    else:
        form = AddDeviceType()
        return render(request, 'devnet_add_device_type.html', locals())


@permission_required('devnet.view_devicetype')
def show_device_type(request):
    html_title = Department.objects.get(name='admin').departtitle.title
    navbar_list = []
    for navbar in Navbar.objects.all().order_by('id'):
        navbar_list.append([navbar.name, navbar.url])
    active_navbar = '设备管理'
    sidebar_list = []
    for sidebar in Navbar.objects.get(name='设备管理').Sidebar.all().order_by('id'):
        sidebar_list.append([sidebar.name, sidebar.url])
    active_sidebar = '查看设备类型'
    device_type_list = []
    for devicetype in Devicetype.objects.all().order_by('id'):
        device_type_dict = {'id_delete': '/device_mgmt/deletedevicetype/' + str(devicetype.id),
                            'id_edit': '/device_mgmt/editdevicetype/' + str(devicetype.id),
                            'name': devicetype.type_name}
        device_type_list.append(device_type_dict)
    return render(request, 'devnet_show_device_type.html', locals())


@permission_required('devnet.delete_devicetype')
def delete_device_type(request, device_type_id):
    html_title = Department.objects.get(name='admin').departtitle.title
    navbar_list = []
    for navbar in Navbar.objects.all().order_by('id'):
        navbar_list.append([navbar.name, navbar.url])
    active_navbar = '设备管理'
    sidebar_list = []
    for sidebar in Navbar.objects.get(name='设备管理').Sidebar.all().order_by('id'):
        sidebar_list.append([sidebar.name, sidebar.url])
    active_sidebar = '查看设备类型'
    d = Devicetype.objects.get(id=device_type_id)
    d.delete()

    device_type_list = []
    for devicetype in Devicetype.objects.all().order_by('id'):
        device_type_dict = {'id_delete': '/device_mgmt/deletedevicetype/' + str(devicetype.id),
                            'id_edit': '/device_mgmt/editdevicetype/' + str(devicetype.id),
                            'name': devicetype.type_name}
        device_type_list.append(device_type_dict)
    return render(request, 'devnet_show_device_type.html', locals())


@permission_required(['devnet.change_devicetype', 'devnet.change_devicesnmp'])
def edit_device_type(request, device_type_id):
    html_title = Department.objects.get(name='admin').departtitle.title
    navbar_list = []
    for navbar in Navbar.objects.all().order_by('id'):
        navbar_list.append([navbar.name, navbar.url])
    active_navbar = '设备管理'
    sidebar_list = []
    for sidebar in Navbar.objects.get(name='设备管理').Sidebar.all().order_by('id'):
        sidebar_list.append([sidebar.name, sidebar.url])
    active_sidebar = '查看设备类型'
    if request.method == 'POST':
        form = EditDeviceType(request.POST)
        if form.is_valid():
            device_id = request.POST.get('device_id')
            device_type_name = request.POST.get('device_type_name')
            oid_list = []
            cpu_usage = request.POST.get('cpu_usage')
            oid_list.append(['cpu_usage', cpu_usage])
            mem_usage = request.POST.get('mem_usage')
            oid_list.append(['mem_usage', mem_usage])
            mem_free = request.POST.get('mem_free')
            oid_list.append(['mem_free', mem_free])
            if_name = request.POST.get('if_name')
            oid_list.append(['if_name', if_name])
            if_speed = request.POST.get('if_speed')
            oid_list.append(['if_speed', if_speed])
            if_state = request.POST.get('if_state')
            oid_list.append(['if_state', if_state])
            if_in_bytes = request.POST.get('if_in_bytes')
            oid_list.append(['if_in_bytes', if_in_bytes])
            if_out_bytes = request.POST.get('if_out_bytes')
            oid_list.append(['if_out_bytes', if_out_bytes])

            d = Devicetype.objects.get(id=device_id)
            # 保存名字
            d.type_name = device_type_name
            d.save()
            for x in oid_list:
                device_snmp_oid = d.devicesnmp.get(snmp_type__snmp_type=x[0])
                device_snmp_oid.oid = x[1]
                device_snmp_oid.save()

            successmessage = '设备类型编辑成功!'
            return render(request, 'devnet_edit_device_type.html', locals())
        else:
            return render(request, 'devnet_edit_device_type.html', locals())
    else:
        dt = Devicetype.objects.get(id=device_type_id)
        form = EditDeviceType(initial={'device_id': device_type_id,
                                       'device_type_name': dt.type_name,
                                       'cpu_usage': dt.devicesnmp.get(snmp_type__snmp_type='cpu_usage').oid,
                                       'mem_usage': dt.devicesnmp.get(snmp_type__snmp_type='mem_usage').oid,
                                       'mem_free': dt.devicesnmp.get(snmp_type__snmp_type='mem_free').oid,
                                       'if_name': dt.devicesnmp.get(snmp_type__snmp_type='if_name').oid,
                                       'if_speed': dt.devicesnmp.get(snmp_type__snmp_type='if_speed').oid,
                                       'if_state': dt.devicesnmp.get(snmp_type__snmp_type='if_state').oid,
                                       'if_in_bytes': dt.devicesnmp.get(snmp_type__snmp_type='if_in_bytes').oid,
                                       'if_out_bytes': dt.devicesnmp.get(snmp_type__snmp_type='if_out_bytes').oid,
                                       })
        return render(request, 'devnet_edit_device_type.html', locals())


@permission_required('devnet.add_devicedb')
def add_device(request):
    html_title = Department.objects.get(name='admin').departtitle.title
    navbar_list = []
    for navbar in Navbar.objects.all().order_by('id'):
        navbar_list.append([navbar.name, navbar.url])
    active_navbar = '设备管理'
    sidebar_list = []
    for sidebar in Navbar.objects.get(name='设备管理').Sidebar.all().order_by('id'):
        sidebar_list.append([sidebar.name, sidebar.url])
    active_sidebar = '添加设备'
    if request.method == 'POST':
        form = AddDevice(request.POST)
        if form.is_valid():
            # 把设备信息写入Devicedb数据库
            d1 = Devicedb(name=request.POST.get('name'),
                          ip=request.POST.get('ip'),
                          description=request.POST.get('description'),
                          type=Devicetype.objects.get(id=int(request.POST.get('type'))),
                          snmp_enable=request.POST.get('snmp_enable'),
                          snmp_ro_community=request.POST.get('snmp_ro_community'),
                          snmp_rw_community=request.POST.get('snmp_rw_community'),
                          ssh_username=request.POST.get('ssh_username'),
                          ssh_password=request.POST.get('ssh_password'),
                          enable_password=request.POST.get('enable_password'), )
            d1.save()
            successmessage = '设备添加成功!'
            return render(request, 'devnet_add_device.html', locals())
        else:
            return render(request, 'devnet_add_device.html', locals())
    else:
        form = AddDevice()
        return render(request, 'devnet_add_device.html', locals())


@permission_required('devnet.view_devicedb')
def show_device(request):
    html_title = Department.objects.get(name='admin').departtitle.title
    navbar_list = []
    for navbar in Navbar.objects.all().order_by('id'):
        navbar_list.append([navbar.name, navbar.url])
    active_navbar = '设备管理'
    sidebar_list = []
    for sidebar in Navbar.objects.get(name='设备管理').Sidebar.all().order_by('id'):
        sidebar_list.append([sidebar.name, sidebar.url])
    active_sidebar = '查看设备'

    result = Devicedb.objects.all()
    devices_list = []
    for x in result:
        # 产生设备信息的字典
        devices_dict = {}
        # 为了不在模板中拼接字符串,提前为删除和编辑页面产生URI
        # 删除设备URL
        devices_dict['id_delete'] = "/device_mgmt/deletedevice/" + str(x.id)
        # 编辑设备URL
        devices_dict['id_edit'] = "/device_mgmt/editdevice/" + str(x.id)
        # 设备名称
        devices_dict['name'] = x.name
        # 设备IP地址
        devices_dict['ip'] = x.ip
        try:
            reachable_info = x.reachable.all().order_by('-id')[0]
            devices_dict['snmp_reachable'] = reachable_info.snmp_reachable
            devices_dict['ssh_reachable'] = reachable_info.ssh_reachable
        except IndexError:
            devices_dict['snmp_reachable'] = False
            devices_dict['ssh_reachable'] = False

        try:
            devices_dict['cpu_max'] = x.cpu_usage.filter(record_datetime__gt=datetime.now() - timedelta(hours=cpu_max_interval)).aggregate(Max('cpu_usage')).get('cpu_usage__max')
            devices_dict['cpu_current'] = x.cpu_usage.all().order_by('-id')[0].cpu_usage
        except IndexError:
            devices_dict['cpu_max'] = 0
            devices_dict['cpu_current'] = 0
        try:
            devices_dict['mem_max'] = x.mem_usage.filter(record_datetime__gt=datetime.now() - timedelta(hours=mem_max_interval)).aggregate(Max('mem_usage')).get('mem_usage__max')
            devices_dict['mem_current'] = x.mem_usage.all().order_by('-id')[0].mem_usage
        except IndexError:
            devices_dict['mem_max'] = 0
            devices_dict['mem_current'] = 0
        if_count = 0
        for if_info in x.interface.all():
            try:
                if if_info.interface_state.all().order_by('-id')[0].state and \
                        if_info.interface_in_bytes.all().order_by('-id')[0].in_bytes and \
                        if_info.interface_out_bytes.all().order_by('-id')[0].out_bytes:
                    if_count += 1
            except IndexError:
                if_count = 0
        devices_dict['ifs'] = if_count
        # 把设备信息添加到字典,再添加到devices_list清单
        devices_list.append(devices_dict)
    return render(request, 'devnet_show_devices.html', locals())


@permission_required('devnet.delete_devicedb')
def delete_device(request, device_id):
    html_title = Department.objects.get(name='admin').departtitle.title
    navbar_list = []
    for navbar in Navbar.objects.all().order_by('id'):
        navbar_list.append([navbar.name, navbar.url])
    active_navbar = '设备管理'
    sidebar_list = []
    for sidebar in Navbar.objects.get(name='设备管理').Sidebar.all().order_by('id'):
        sidebar_list.append([sidebar.name, sidebar.url])
    active_sidebar = '查看设备'

    d = Devicedb.objects.get(id=device_id)
    d.delete()
    result = Devicedb.objects.all()
    devices_list = []
    for x in result:
        # 产生设备信息的字典
        devices_dict = {}
        # 为了不在模板中拼接字符串,提前为删除和编辑页面产生URI
        # 删除设备URL
        devices_dict['id_delete'] = "/device_mgmt/deletedevice/" + str(x.id)
        # 编辑设备URL
        devices_dict['id_edit'] = "/device_mgmt/editdevice/" + str(x.id)
        # 设备名称
        devices_dict['name'] = x.name
        # 设备IP地址
        devices_dict['ip'] = x.ip
        reachable_info = x.reachable.all().order_by('-id')[0]
        devices_dict['snmp_reachable'] = reachable_info.snmp_reachable
        devices_dict['ssh_reachable'] = reachable_info.ssh_reachable

        devices_dict['cpu_max'] = x.cpu_usage.all().aggregate(Max('cpu_usage')).get('cpu_usage__max')
        devices_dict['cpu_current'] = x.cpu_usage.all().order_by('-id')[0].cpu_usage
        devices_dict['mem_max'] = x.mem_usage.all().aggregate(Max('mem_usage')).get('mem_usage__max')
        devices_dict['mem_current'] = x.mem_usage.all().order_by('-id')[0].mem_usage

        if_count = 0
        for if_info in x.interface.all():
            if if_info.interface_state.all().order_by('-id')[0].state and \
                    if_info.interface_in_bytes.all().order_by('-id')[0].in_bytes and \
                    if_info.interface_out_bytes.all().order_by('-id')[0].out_bytes:
                if_count += 1
        devices_dict['ifs'] = if_count
        # 把设备信息添加到字典,再添加到devices_list清单
        devices_list.append(devices_dict)
    successmessage = '设备删除成功!'
    return render(request, 'devnet_show_devices.html', locals())


@permission_required('devnet.change_devicedb')
def edit_device(request, device_id):
    html_title = Department.objects.get(name='admin').departtitle.title
    navbar_list = []
    for navbar in Navbar.objects.all().order_by('id'):
        navbar_list.append([navbar.name, navbar.url])
    active_navbar = '设备管理'
    sidebar_list = []
    for sidebar in Navbar.objects.get(name='设备管理').Sidebar.all().order_by('id'):
        sidebar_list.append([sidebar.name, sidebar.url])
    active_sidebar = '查看设备'
    if request.method == 'POST':
        form = EditDevice(request.POST)
        if form.is_valid():
            d = Devicedb.objects.get(id=request.POST.get('id'))
            d.name = request.POST.get('name')
            d.ip = request.POST.get('ip')
            d.description = request.POST.get('description')
            d.type = Devicetype.objects.get(id=int(request.POST.get('type')))
            d.snmp_enable = request.POST.get('snmp_enable')
            d.snmp_ro_community = request.POST.get('snmp_ro_community')
            d.snmp_rw_community = request.POST.get('snmp_rw_community')
            d.ssh_username = request.POST.get('ssh_username')
            d.ssh_password = request.POST.get('ssh_password')
            d.enable_password = request.POST.get('enable_password')
            d.save()

            successmessage = '设备修改成功!'
            return render(request, 'devnet_add_device.html', locals())
        else:
            return render(request, 'devnet_add_device.html', locals())
    else:
        d = Devicedb.objects.get(id=device_id)
        form = EditDevice(initial={'id': d.id,
                                   'name': d.name,
                                   'ip': d.ip,
                                   'description': d.description,
                                   'type': d.type.id,
                                   'snmp_enable': d.snmp_enable,
                                   'snmp_ro_community': d.snmp_ro_community,
                                   'snmp_rw_community': d.snmp_rw_community,
                                   'ssh_username': d.ssh_username,
                                   'ssh_password': d.ssh_password,
                                   'enable_password': d.enable_password
                                   })
        return render(request, 'devnet_add_device.html', locals())


